package cn.mengfly.testnrz.im.client;

import cn.mengfly.testnrz.im.client.bean.User;
import cn.mengfly.testnrz.im.client.handler.ChatMsgHandler;
import cn.mengfly.testnrz.im.client.handler.ExceptionHandler;
import cn.mengfly.testnrz.im.client.handler.LoginResponseHandler;
import cn.mengfly.testnrz.im.client.sender.ChatSender;
import cn.mengfly.testnrz.im.client.sender.LoginSender;
import cn.mengfly.testnrz.im.codec.ProtobufDecoder;
import cn.mengfly.testnrz.im.codec.ProtobufEncoder;
import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.PooledByteBufAllocator;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.util.concurrent.GenericFutureListener;
import lombok.Data;

import java.io.Closeable;
import java.io.IOException;

@Data
public class NettyClient implements Closeable {

    private String host;
    private int port;

    private ChatMsgHandler chatMsgHandler = new ChatMsgHandler();
    private LoginResponseHandler loginResponseHandler = new LoginResponseHandler();
    private ExceptionHandler exceptionHandler = new ExceptionHandler();

    private Channel channel;
    private ChatSender sender;
    private LoginSender loginSender;

    private boolean initFlag = true;
    private User user;
    private GenericFutureListener<ChannelFuture> connectedListener;

    private Bootstrap b;
    private EventLoopGroup g;

    public NettyClient(String host, Integer port) {
        b = new Bootstrap();
        g = new NioEventLoopGroup();
        this.host = host;
        this.port = port;
    }

    public void doConnect() {
        try {
            b.group(g);
            b.channel(NioSocketChannel.class);
            b.option(ChannelOption.SO_KEEPALIVE, true);
            b.option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT);
            b.remoteAddress(host, port);

            b.handler(new ChannelInitializer<SocketChannel>() {
                @Override
                protected void initChannel(SocketChannel ch) {
                    ch.pipeline().addLast("decoder", new ProtobufDecoder());
                    ch.pipeline().addLast("encoder", new ProtobufEncoder());
                    ch.pipeline().addLast(loginResponseHandler);
                    ch.pipeline().addLast(chatMsgHandler);
                    ch.pipeline().addLast(exceptionHandler);
                }
            });
            System.out.println("客户端开始连接【IM】");
            ChannelFuture connect = b.connect();
            connect.addListener(connectedListener);
        } catch (Exception e) {
            System.out.println("连接失败" + e.getMessage());
        }
    }

    @Override
    public void close() throws IOException {
        g.shutdownGracefully();
    }
}
